package com.example.springcloudwinter.filter;

import com.example.springcloudwinter.properties.IgnoreWhiteProperties;
import com.example.springcloudwinter.token.AuthenticationToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.ws.rs.core.UriBuilder;
import java.net.URI;
import java.nio.charset.StandardCharsets;

@Component
public class AuthorizationFilter implements GlobalFilter, Ordered {

    @Autowired
    private IgnoreWhiteProperties whiteList;

    @Autowired
    private AuthenticationToken authenticationToken;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //白名单过滤
        if (ignoreWhiteList(exchange.getRequest().getPath().toString())){
            logger.info(exchange.getRequest().getPath().toString());
            return chain.filter(exchange);
        }

        //获取token
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (token==null){
            // 设置响应头 返回类型为json
            exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
            // 设置响应体
            String body = "{\"code\":301,\"detail\":401}";
            return exchange.getResponse().writeWith(Mono.just(
                    makeResponseBody(body,exchange)
            ));
        }else if(!authenticationToken.verify(token)){
            // 设置响应头 返回类型为json
            exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
            // 设置响应体
            String body = "{\"code\":301,\"detail\":402}";
            return exchange.getResponse().writeWith(Mono.just(
                    makeResponseBody(body,exchange)
            ));
        }else {
            //获取token中的userId
            logger.info(exchange.getRequest().getURI().toString());
            String tokenUserId = authenticationToken.getBody(token,"userId");

            //重制uri
            UriBuilder uriBuilder=UriBuilder.fromUri(exchange.getRequest().getURI());
            uriBuilder.replaceQueryParam("userId",tokenUserId);
            URI newUri = uriBuilder.build();

            //重制请求
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .uri(newUri)
                    .build();
            ServerWebExchange newExchange = exchange.mutate().request(request).build();
            logger.info(newExchange.getRequest().getURI().toString());
            return chain.filter(newExchange);
        }
    }

    private boolean ignoreWhiteList(String path){
        if (whiteList!=null)
            for (String u : whiteList.getWhiteList()) {
                if (path.startsWith(u)){
                    return true;
                }
            }
        return false;
    }

    private DataBuffer makeResponseBody(String body,ServerWebExchange exchange){
        byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
        return exchange.getResponse().bufferFactory().wrap(bytes);
    }

    @Override
    public int getOrder() {
        return -200;
    }
}